use nacos_rust_client::client::naming_client::{Instance, NamingClient};
use nacos_rust_client::client::{AuthInfo, ClientBuilder};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tracing::{error, info, warn};

/// Nacos 配置
#[derive(Debug, Clone)]
pub struct NacosConfig {
    /// Nacos 服务器地址
    pub server_addr: String,
    /// 命名空间ID
    pub namespace_id: String,
    /// 认证信息
    pub auth_info: Option<AuthInfo>,
    /// 是否启用gRPC
    pub use_grpc: bool,
}

impl Default for NacosConfig {
    fn default() -> Self {
        Self {
            server_addr: "152.136.130.146:8848".to_string(),
            namespace_id: "public".to_string(),
            auth_info: None,
            use_grpc: true,
        }
    }
}

/// 服务配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceConfig {
    /// 服务名称
    pub service_name: String,
    /// 应用名称
    pub app_name: String,
    /// 服务端口
    pub port: u32,
    /// 服务IP (如果不指定则自动获取)
    pub ip: Option<String>,
    /// 服务分组
    pub group: String,
}

impl ServiceConfig {
    pub fn new(service_name: &str, app_name: &str, port: u32) -> Self {
        Self {
            service_name: service_name.to_string(),
            app_name: app_name.to_string(),
            port,
            ip: None,
            group: "DEFAULT_GROUP".to_string(),
        }
    }
}

/// Nacos 注册中心管理器
pub struct NacosRegistry {
    config: NacosConfig,
    client: Arc<NamingClient>,
}

impl NacosRegistry {
    /// 创建新的 Nacos 注册中心管理器
    pub fn new(config: NacosConfig, app_name: &str) -> Self {
        let client = ClientBuilder::new()
            .set_endpoint_addrs(&config.server_addr)
            .set_auth_info(config.auth_info.clone())
            .set_tenant(config.namespace_id.clone())
            .set_use_grpc(config.use_grpc)
            .set_app_name(app_name.to_owned())
            .build_naming_client();

        Self { config, client }
    }

    /// 使用默认配置创建
    pub fn with_default(app_name: &str) -> Self {
        Self::new(NacosConfig::default(), app_name)
    }

    /// 注册服务
    pub fn register_service(
        &self,
        service_config: &ServiceConfig,
    ) -> Result<(), Box<dyn std::error::Error>> {
        let ip = match &service_config.ip {
            Some(ip) => ip.clone(),
            None => local_ipaddress::get().unwrap_or_else(|| "127.0.0.1".to_string()),
        };

        info!(
            "🔄 注册服务到Nacos: {}:{} -> {}",
            service_config.service_name, ip, service_config.port
        );

        let instance = Instance::new_simple(
            &ip,
            service_config.port,
            &service_config.service_name,
            &service_config.group,
        );

        self.client.register(instance);
        info!(
            "✅ 服务注册成功: {} ({}:{})",
            service_config.service_name, ip, service_config.port
        );
        Ok(())
    }

    /// 批量注册服务
    pub fn register_services(
        &self,
        services: &[ServiceConfig],
    ) -> Result<(), Box<dyn std::error::Error>> {
        info!("🔄 批量注册 {} 个服务到Nacos", services.len());

        for service in services {
            if let Err(e) = self.register_service(service) {
                error!(
                    "❌ 批量注册中断，服务 {} 注册失败: {:?}",
                    service.service_name, e
                );
                return Err(e);
            }
        }

        info!("✅ 所有服务注册完成");
        Ok(())
    }

    /// 获取命名客户端
    pub fn get_naming_client(&self) -> Arc<NamingClient> {
        self.client.clone()
    }

    /// 注销服务 (暂时不可用，nacos_rust_client 0.3.2版本没有此方法)
    pub fn deregister_service(
        &self,
        service_config: &ServiceConfig,
    ) -> Result<(), Box<dyn std::error::Error>> {
        warn!("⚠️ 服务注销功能在当前版本不可用: {}", service_config.service_name);
        Ok(())
    }

    /// 健康检查 (简化版本，不进行实际查询)
    pub fn health_check(&self, service_name: &str) -> bool {
        info!("✅ 服务健康检查 (简化版): {}", service_name);
        true // 简化实现，总是返回true
    }
}

/// 常用服务配置预设
pub mod presets {
    use super::ServiceConfig;

    /// System 服务配置
    pub fn system_service() -> ServiceConfig {
        ServiceConfig::new("system-service", "system-service", 50051)
    }

    /// Payment 服务配置
    pub fn payment_service() -> ServiceConfig {
        ServiceConfig::new("payment-service", "payment-service", 50053)
    }

    /// Infra Dict 服务配置
    pub fn infra_dict_service() -> ServiceConfig {
        ServiceConfig::new("infra-dict", "infra-service", 50052)
    }

    /// Infra Notice 服务配置
    pub fn infra_notice_service() -> ServiceConfig {
        ServiceConfig::new("infra-notice", "infra-service", 50052)
    }

    /// System Auth 服务配置
    pub fn system_auth_service() -> ServiceConfig {
        ServiceConfig::new("system-auth", "payment-service", 50053)
    }

    /// System Role 服务配置
    pub fn system_role_service() -> ServiceConfig {
        ServiceConfig::new("system-role", "payment-service", 50053)
    }
}
